package com.example.Java8InAction.stream;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

public class FunctionDemo {
    public static void main(String[] args) {
        //1.使用lambda表达式分别将以下功能封装到Function对象中
        //a) 求Integer类型ArrayList中所有元素的平均数
        Function<ArrayList<Integer>, Integer> f1 = (list) -> {
            Integer sum = 0;
            for (Integer integer : list) {
                sum += integer;
            }
            return sum / list.size();
        };

        //b) 将Map<String,Integer>中value存到ArrayList<Integer>中
        Function<Map<String, Integer>, ArrayList<Integer>> f2 = (map) -> {
            Collection<Integer> values = map.values();
            ArrayList<Integer> list = new ArrayList<>();
            list.addAll(values);
            return list;
        };


        //2 将学生姓名和成绩封装到map中
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("岑小村", 59);
        map.put("谷天洛", 82);
        map.put("渣渣辉", 98);
        map.put("蓝小月", 65);
        map.put("皮几万", 70);

        //利用Function求平均成绩
        Integer avg = f2.andThen(f1).apply(map);
        System.out.println("学生平均成绩为：" + avg);

        ArrayList<Integer> arrayList = f2.apply(map);

        arrayList.forEach(integer -> System.out.println(integer));

        //将String hash 得到一个int
        Function<String, Integer> f3 = s -> s.hashCode();
        Integer i = f3.apply("智慧齿轮");
        System.out.println(i);
    }


    @Test
    public void test() {
        Function<Integer, Integer> test1 = i -> i + 1;
        Function<Integer, Integer> test2 = i -> i * i;
        System.out.println(calculate(test1, 5));
        System.out.println(calculate(test2, 5));
    }

    //计算器
    public static Integer calculate(Function<Integer, Integer> test, Integer number) {
        return test.apply(number);
    }

    @Test
    public void test2() {
        Function<Integer, Integer> A = i -> i + 1;
        Function<Integer, Integer> B = i -> i * i;
        System.out.println("F1:" + B.apply(A.apply(5)));
        System.out.println("F2:" + A.apply(B.apply(5)));

        //究极计算结果我已经迷了 所以我准备先执行一个简单的结果
        System.out.println("F3:"+B.compose(A).apply(3)); //计算结果为16 compose先执行参数运算
        System.out.println("F3:"+B.apply(A.apply(3)));

        System.out.println("F4:"+B.andThen(A).apply(3)); //计算结果为10 andThen先执行外部运算
        System.out.println("F4:"+A.apply(B.apply(3)));

        //两运算的我迷迷糊糊的都能写出来,我试试三个的
        System.out.println("F5:" + B.compose(A).andThen(A).apply(3));
        System.err.println("F5:" + A.apply(B.apply(A.apply(3))));
        //25  26 27*27  730
        System.out.println("究极计算 结果:"+B.compose(A).compose(A).andThen(A).apply(5));
        System.out.println("究极计算 结果:"+A.apply(B.apply(A.apply(A.apply(5)))));
    }

    @Test
    public void test3(){
        Function<Integer,Integer> A=i->i+1;
        Function<Integer,Integer> B=i->i*i;
        System.out.println("F1:"+B.apply(A.apply(5)));
        System.out.println("F1:"+B.compose(A).apply(5));
        System.out.println("F2:"+A.apply(B.apply(5)));
        System.out.println("F2:"+B.andThen(A).apply(5));
    }
}
